﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;

namespace Comp477Project
{
    class EffectsHandler
    {
        public List<ParticleSystem> effects;
        public List<ParticleSystem> cloud;
        public List<ParticleSystem> explosion;
        public List<ParticleSystem> smoke;
        public List<ParticleSystem> snow;
     
        public List<Primitives3D.GeometricPrimitive> particleModel;
        static Random rand = new Random();
        double timer, dt;
        SoundEffect boom;
        double timer1;
        float explosionInterval;
        public EffectsHandler(GraphicsDevice graphicsDevice, ref Matrix projection,ref SoundEffect boom)
        {
            explosionInterval = 8000;
            this.boom = boom;
            this.timer1 = 0;
            particleModel = new List<Primitives3D.GeometricPrimitive>();
            particleModel.Add(new Primitives3D.CubePrimitive(graphicsDevice));
            particleModel.Add(new Primitives3D.CylinderPrimitive(graphicsDevice, 1, 1, 8));
            particleModel.Add(new Primitives3D.SpherePrimitive(graphicsDevice, 1, 8));
            particleModel.Add(new Primitives3D.TorusPrimitive(graphicsDevice, 1, 0.333f, 8));
            effects = new List<ParticleSystem>();
            cloud = new List<ParticleSystem>();
            explosion=new List<ParticleSystem>();
            smoke=new List<ParticleSystem>();
            snow = new List<ParticleSystem>();
            float worldSize = 100, snowWorldSize = 35;
            timer = 0;
            dt = 10;
            // Sample
            //effects.Add(new ParticleSystem(particleModel, ref projection, type, N, duration, gravity, particleSize, sizeOffset, sizeMod, color, alphaChange, speed,
            //                                        speedOffset, rotate, sourcePosition, sourceOffset, direction, directionOffset, wind, spawn));
            // Explosion
            Vector3 tipPos = new Vector3(0.25f, 1.5f, 1);
            explosion.Add(new ParticleSystem(particleModel, ref projection, 2, 1000, 2000, true, 0.05f, 0.01f, 0.02f, Color.OrangeRed, true, 0.02f,
                                                  0.02f, false, tipPos, new Vector3(0.15f, 0.10f, 0.15f), new Vector3(0, 1, 0), new Vector3(0.75f, 0.0f, 0.75f), new Vector3(0, 0, 0), explosionInterval));
           explosion.Add(new ParticleSystem(particleModel, ref projection, 2, 1000, 2000, true, 0.05f, 0.01f, 0.02f, Color.DarkOrange, true, 0.02f,
                                                  0.02f, true, tipPos, new Vector3(0.15f, 0.10f, 0.15f), new Vector3(0, 1, 0), new Vector3(0.75f, 0.0f, 0.75f), new Vector3(0, 0, 0), explosionInterval));
            // soot
            explosion.Add(new ParticleSystem(particleModel, ref projection, 4, 500, 3500, true, 0.05f, 0.05f, 0.00009f, Color.OrangeRed, true, 0.02f,
                                                  0.02f, true, tipPos, new Vector3(0.25f, 0.10f, 0.25f), new Vector3(0, 1, 0), new Vector3(0.75f, 0.0f, 0.75f), new Vector3(0, 0, 0), explosionInterval));
           explosion.Add(new ParticleSystem(particleModel, ref projection, 2, 700, 3500, true, 0.05f, 0.05f, 0.00009f, Color.Black, true, 0.02f,
                                                 0.02f, true, tipPos, new Vector3(0.25f, 0.10f, 0.25f), new Vector3(0, 1, 0), new Vector3(0.75f, 0.0f, 0.75f), new Vector3(0, 0, 0), explosionInterval));
           // debris
           explosion.Add(new ParticleSystem(particleModel, ref projection, 1, 15, 5000, true, 0.03f, 0.02f, 0.001f, Color.Black, false, 0.02f,
                                                 0.02f, true, tipPos, new Vector3(0.25f, 0.10f, 0.25f), new Vector3(0, 1, 0), new Vector3(2.75f, 1.0f, 2.75f), new Vector3(0, 0, 0), explosionInterval));
           explosion.Add(new ParticleSystem(particleModel, ref projection, 4, 15, 5000, true, 0.03f, 0.02f, 0.001f, Color.Black, false, 0.02f,
                                                 0.02f, true, tipPos, new Vector3(0.25f, 0.10f, 0.25f), new Vector3(0, 1, 0), new Vector3(2.75f, 1.0f, 2.75f), new Vector3(0, 0, 0), explosionInterval));
            // Snow
            snow.Add(new ParticleSystem(particleModel, ref projection, 2, 2000, 7500, false, 0.05f, 0.05f, 0.0f, Color.White, false, 0.02f,
                                                    0.01f, false, new Vector3(-snowWorldSize / 2, 7.5f, -snowWorldSize / 2), new Vector3(snowWorldSize, 0.0f, snowWorldSize), new Vector3(0, -1, 0), new Vector3(0.1f, 0, 0.1f), new Vector3(0, 0, 0), 0));
            // Cloud
            Color cloudColor = Color.White;
            cloudColor.A = 200;
            for (int clouds = 0; clouds != 75; clouds++)
            {
                Vector3 position = new Vector3((float)rand.NextDouble() * worldSize - (worldSize / 2),
                                                (float)rand.NextDouble() * 5 + 10,
                                                (float)rand.NextDouble() * worldSize - (worldSize / 2));
                float duration = 45000 + (float)rand.NextDouble() * 35000;
                cloud.Add(new ParticleSystem(particleModel, ref projection, 2, 35, duration, false, 2f, 1.5f, 0.0001f, cloudColor, false, 0.01f,
                                                    0, false, position, new Vector3(7.50f, 1.50f, 4.50f), new Vector3(1, 0, 0), new Vector3(0, 0, 0), new Vector3(0, 0, 0), duration + 1000));
            }
            // Smoke
            Color smokeColor = Color.Black;
            //Vector3 tipPos = new Vector3(0.25f, 1.5f, 1);
            float smokeDuration = 5000;
            smoke.Add(new ParticleSystem(particleModel, ref projection, 2, 200, smokeDuration, false, 0.1f, 0.05f, 0.001f, smokeColor, true, 0.005f,
                                                    0.01f, false, tipPos, new Vector3(0.25f, 0.10f, 0.25f), new Vector3(0, 1, 0), new Vector3(0.1f, 0, 0.1f), new Vector3(0, 0, 0), 0));
          
        }

        public void Update(GameTime gametime,bool[] param)
        {
            timer += gametime.ElapsedGameTime.TotalMilliseconds;
            if (timer > dt)
            {

                if (param[0] == true || param[7] == true)
                {
                    foreach (ParticleSystem cl in cloud)
                    {
                        
                        cl.Update(gametime);
                       
                        //if (cl.timer > cl.duration - (cl.duration / 2))
                        //{
                        //    cl.alphaChange = true;
                           
                        //}
                        //if (cl.timer == 0)
                        //{

                        //}
                        if (param[2])
                        {
                            cl.color = Color.Gray;
                        }
                        else if(param[2]==false)
                        {
                            cl.color = Color.White;
                        }
                    }

                }
                if (param[1] == true || param[7] == true)
                {
                    foreach (ParticleSystem sn in snow)
                    {
                        sn.Update(gametime);
                    }
                }
                if (param[3] == true || param[7] == true)
                {
                    foreach (ParticleSystem sm in smoke)
                    {
                        sm.Update(gametime);
                    }
                }
                if (param[4] == true || param[7]==true)
                {
                    
                    foreach (ParticleSystem ex in explosion)
                    {
                        ex.Update(gametime);
                       
                       
                    }
                    if (timer1 == 0)
                    {
                        boom.Play();
                        //Console.WriteLine("Im playing");
                    }
                    timer1 += gametime.ElapsedGameTime.TotalMilliseconds;
                    
                }
               
               
                timer = 0;
            }
            if (timer1 > explosionInterval)
            {
                timer1 = 0;
            }
            
        }

        public void Draw(Matrix view, bool[] param)
        {
            //foreach (ParticleSystem ps in effects)
            //{
            //    ps.Draw(view);
            //}
            if (param[0] == true || param[7] == true)
            {
                foreach (ParticleSystem cl in cloud)
                {
                    cl.Draw(view);
                }
            }
            if (param[1] == true || param[7] == true)
            {
                foreach (ParticleSystem sn in snow)
                {
                    sn.Draw(view);
                }
            }
            if (param[3] == true || param[7] == true)
            {
                foreach (ParticleSystem sm in smoke)
                {
                    sm.Draw(view);
                }
            }
            if (param[4] == true || param[7] == true)
            {
                foreach (ParticleSystem ex in explosion)
                {
                    ex.Draw(view);
                }
            }
         
        }
    }
}
